package com.yfqy.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yfqy.admin.conf.Idgenerator.SnowflakeIdGenerator;
import com.yfqy.admin.constant.MyConstants;
import com.yfqy.admin.domain.dto.product.ProductQuery;
import com.yfqy.admin.domain.dto.product.ProductSkuDTO;
import com.yfqy.admin.domain.dto.product.ProductSpuDTO;
import com.yfqy.admin.domain.dto.product.UpAndDownProduct;
import com.yfqy.admin.domain.entity.ProductSku;
import com.yfqy.admin.domain.entity.ProductSpu;
import com.yfqy.admin.domain.entity.ProductSpuImages;
import com.yfqy.admin.domain.mapper.ProductSkuMapper;
import com.yfqy.admin.domain.mapper.ProductSpuImagesMapper;
import com.yfqy.admin.domain.mapper.ProductSpuMapper;
import com.yfqy.admin.security.login.LoginUserInfo;
import com.yfqy.admin.service.ProductPromotionService;
import com.yfqy.admin.service.ProductService;
import com.yfqy.admin.transform.CategoryNameTranslator;
import com.yfqy.admin.transform.LabelNameTranslator;
import com.yfqy.admin.transform.UserNameTranslator;
import com.yfqy.admin.util.AuthUserContext;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ProductServiceImpl implements ProductService {

    private static final Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);

    private final ProductSpuMapper productSpuMapper;
    private final ProductSkuMapper productSkuMapper;
    private final SnowflakeIdGenerator idGenerator;
    private final UserNameTranslator userNameTranslator;
    private final LabelNameTranslator labelNameTranslator;
    private final CategoryNameTranslator categoryNameTranslator;
    private final ProductSpuImagesMapper productSpuImagesMapper;
    private final ProductPromotionService promotionService;


    @Override
    @Transactional
    public int addProduct(ProductSpuDTO addProduct) {
        Long getSpuIdByName = productSpuMapper.selectOneSpuByName(addProduct.getSpuName());
        if (getSpuIdByName != null) {
            throw new IllegalArgumentException("商品已存在，不可重复新增");
        }
        Long createdBy = getCurrentUserId();
        ProductSpu productSpu = BeanUtil.toBean(addProduct, ProductSpu.class);
        Long spuId = idGenerator.nextId();
        productSpu.setId(spuId);
        productSpu.setSpuCode("SPU" + spuId);
        productSpu.setCreatedBy(createdBy);
        productSpu.setModifiedBy(createdBy);
        int inserted = productSpuMapper.insertSelective(productSpu);
        logger.info("新增商品成功-inserted：{}，productSpu：{}", inserted, productSpu);
        // spu新增成功
        if (inserted > 0) {
            // 开始保存spu图片
            ProductSpuImages spuImages = new ProductSpuImages();
            spuImages.setId(productSpu.getId());
            spuImages.setMainImages(String.join(",", addProduct.getMainImageList()));
            spuImages.setDetailImages(String.join(",", addProduct.getDetailImageList()));
            productSpuImagesMapper.insert(spuImages);
            logger.info("新增商品成功-新增商品图片成功");
            // 开始新增sku
            List<ProductSku> skus = new ArrayList<>();
            List<ProductSkuDTO> productSkus = addProduct.getProductSkus();
            productSkus.forEach(skuDTO -> {
                ProductSku sku = BeanUtil.toBean(skuDTO, ProductSku.class);
                sku.setId(idGenerator.nextId());
                sku.setSpuId(spuId);
                sku.setSkuCode("SKU" + sku.getId());
                sku.setCreatedBy(createdBy);
                sku.setModifiedBy(createdBy);
                skus.add(sku);
            });
            int batch = productSkuMapper.insertBatch(skus);
            logger.info("新增商品成功-新增sku列表成功：{}，新增SKU列表：{}", batch, skus);
        }
        return inserted;
    }

    @Override
    public ProductSpuDTO detail(Long id) {
        ProductSpuDTO productSpuDTO = productSpuMapper.selectSpuDTOById(id);
        if (productSpuDTO == null) {
            throw new IllegalArgumentException("商品信息不存在");
        }
        userNameTranslator.translationUser(productSpuDTO);
        List<ProductSkuDTO> skuDTOS = productSkuMapper.selectSkuDTOsBySpuId(id);
        userNameTranslator.translationUser(skuDTOS);
        ProductSpuImages spuImages = productSpuImagesMapper.selectByPrimaryKey(id);
        productSpuDTO.setMainImageList(Arrays.asList(spuImages.getMainImages().split(",")));
        productSpuDTO.setDetailImageList(Arrays.asList(spuImages.getDetailImages().split(",")));
        productSpuDTO.setProductSkus(skuDTOS);
        return productSpuDTO;
    }

    @Override
    public PageInfo<ProductSpuDTO> pageList(ProductQuery productQuery) {
        PageHelper.startPage(productQuery.getPageIndex(), productQuery.getPageSize());
        List<ProductSpuDTO> spuDTOS = productSpuMapper.selectPageListByCondition(productQuery);
        if (CollUtil.isNotEmpty(spuDTOS)) {
            userNameTranslator.translationUser(spuDTOS);
            labelNameTranslator.translationLabel(spuDTOS);
            categoryNameTranslator.translationCategory(spuDTOS);
            /*spuDTOS.forEach(spuDTO -> {
                spuDTO.setMainImageList(Lists.newArrayList(spuDTO.getMainImage().split(",")[0]));
            });*/
        }
        PageInfo<ProductSpuDTO> pageInfo = new PageInfo<>(spuDTOS);
        PageHelper.clearPage();
        return pageInfo;
    }

    @Override
    @Transactional
    public int upAndDown(UpAndDownProduct upAndDownProduct) {
        ProductSpu productSpu = productSpuMapper.selectByPrimaryKey(upAndDownProduct.getId());
        if (productSpu == null) {
            throw new IllegalArgumentException("商品信息不存在");
        }
        // 商品上下架不需要考虑商品库存是否被其他线程锁定
        int updated = productSpuMapper.updateStatus(upAndDownProduct.getId(), upAndDownProduct.getStatus(), getCurrentUserId());
        if (updated > 0 && upAndDownProduct.getStatus() == MyConstants.BT2) {
            // down product promotion
            int end = promotionService.endPromotionBySpuId(upAndDownProduct.getId());
            logger.info("商品下架-商品活动下架，endPromotionBySpuId:{}", end);
        }
        return updated;
    }

    @Override
    @Transactional
    public int modifyProduct(ProductSpuDTO modifyProduct) {
        // 1、修改商品spu
        logger.info("编辑商品入参modifyProduct：{}", JSONUtil.toJsonStr(modifyProduct));
        if (modifyProduct.getId() == null) {
            throw new IllegalArgumentException("id不能为空");
        }
        ProductSpu productSpu = productSpuMapper.selectByPrimaryKey(modifyProduct.getId());
        if (productSpu == null) {
            throw new IllegalArgumentException("商品信息不存在");
        }
        if (productSpu.getStatus() == MyConstants.BT1) {
            throw new IllegalArgumentException("请将商品下架后再进行编辑操作，可防止超卖少买问题");
        }
        Long getSpuIdByName = productSpuMapper.selectOneSpuByName(modifyProduct.getSpuName());
        if (getSpuIdByName != null && !getSpuIdByName.equals(modifyProduct.getId())) {
            throw new IllegalArgumentException("商品名称已存在，不可重复使用");
        }
        Long modifiedBy = getCurrentUserId();
        BeanUtil.copyProperties(modifyProduct, productSpu, CopyOptions.create().setIgnoreNullValue(true));
        productSpu.setModifiedBy(modifiedBy);
        int updatedSpuCount = productSpuMapper.updateByPrimaryKeySelective(productSpu);
        logger.info("修改商品updatedSpuCount：{}，modifiedBy={}", updatedSpuCount, modifiedBy);

        // 2、修改spu图片数据
        ProductSpuImages spuImages = new ProductSpuImages();
        spuImages.setId(productSpu.getId());
        spuImages.setMainImages(String.join(",", modifyProduct.getMainImageList()));
        spuImages.setDetailImages(String.join(",", modifyProduct.getDetailImageList()));
        productSpuImagesMapper.updateByPrimaryKey(spuImages);

        // 3、修改sku列表
        // 获取数据库中已有的SKU
        List<ProductSku> skuList = productSkuMapper.selectSkusBySpuId(modifyProduct.getId());
        Map<Long, ProductSku> skuMap = skuList.stream().collect(Collectors.toMap(ProductSku::getId, Function.identity()));

        // 前端传过来的SKU：有新增的（id为空），有编辑的（id不为空）
        List<ProductSkuDTO> productSkuDTOs = modifyProduct.getProductSkus();

        // 初始化三个操作集合
        List<ProductSku> batchInsert = new ArrayList<>();
        List<ProductSku> batchUpdate = new ArrayList<>();
        List<Long> batchDelete = new ArrayList<>();

        // 1. 处理新增和更新的SKU
        productSkuDTOs.forEach(skuDTO -> {
            if (skuDTO.getId() == null) {
                // 新增的SKU
                ProductSku productSku = BeanUtil.toBean(skuDTO, ProductSku.class);
                productSku.setId(idGenerator.nextId());
                productSku.setSkuCode("SKU" + productSku.getId());
                productSku.setSpuId(modifyProduct.getId());
                productSku.setCreatedBy(modifiedBy);
                productSku.setModifiedBy(modifiedBy);
                batchInsert.add(productSku);
            } else if (skuMap.get(skuDTO.getId()) != null) {
                // 更新的SKU
                ProductSku update = skuMap.get(skuDTO.getId());
                BeanUtil.copyProperties(skuDTO, update, CopyOptions.create().setIgnoreNullValue(true));
                // update.setModifiedBy(modifiedBy);
                batchUpdate.add(update);
            }
        });

        // 2. 处理删除的SKU - 找出数据库中存在但前端没有传过来的SKU
        Set<Long> frontendSkuIds = productSkuDTOs.stream()
                .map(ProductSkuDTO::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        skuList.forEach(dbSku -> {
            if (!frontendSkuIds.contains(dbSku.getId())) {
                // 数据库中存在但前端没有传过来的SKU，需要删除
                batchDelete.add(dbSku.getId());
            }
        });

        // 3. 执行批量操作（根据你的实际需求调用Mapper）
        if (!batchInsert.isEmpty()) {
            int insertedCount = productSkuMapper.insertBatch(batchInsert);
            logger.info("spuId:{}, 新增sku个数；{}", modifyProduct.getId(), insertedCount);
        }
        if (!batchUpdate.isEmpty()) {
            int updatedCount = productSkuMapper.batchUpdate(batchUpdate, modifiedBy);
            logger.info("spuId:{}, 修改sku个数；{}", modifyProduct.getId(), updatedCount);
        }
        if (!batchDelete.isEmpty()) {
            int deleteCount = productSkuMapper.batchDeleteByIds(batchDelete, modifiedBy);
            logger.info("spuId:{}, 删除sku个数；{}", modifyProduct.getId(), deleteCount);
        }
        return 1;
    }

    @Override
    public List<ProductSkuDTO> skuList(Long spuId) {
        List<ProductSkuDTO> skuDTOS = productSkuMapper.selectSkuDTOsBySpuId(spuId);
        userNameTranslator.translationUser(skuDTOS);
        return skuDTOS;
    }

    private Long getCurrentUserId() {
        LoginUserInfo loginUserInfo = AuthUserContext.getLocalAuthUser();
        return Objects.nonNull(loginUserInfo) ? loginUserInfo.getId() : MyConstants._L1;
    }
}
